// 低代码表单配置
var VUE_LOW_CODE_FORM_CONFIG_V2 = {
    data() {
        return {
            componentOptionGroupList: PAGE_CONFIG_COMPONENT_OPTIONS,
            // 表单配置当前选中面板, fields/component/highComponent/chart
            formConfigCollapse: 'layout',
            formConfigLeftTab: 'component',
            formConfigRightTab: 'detail',
            // 表单配置拖拽类型
            formConfigDragType: {
                option: {code: 'option', text: '被拖拽的是左侧组件选项'},
                inner: {code: 'inner', text: '被拖拽的是表单配置容器中已有的元素'},
            },
            // 当前正在拖拽的组件
            dragContext: {
                // 拖拽类型, formConfigDragType
                dragType: '',
                dragEleOption: null,
            },
            // 表单(页面)配置对象
            formPageConfig: {
                // 元素(组件)集合
                elementList: []
            },
            // 代码生成配置
            formData: {},
            // 当前选中的组件
            formConfigActiveEle: null,
        };
    },
    computed: {
        // dom树
        domTree() {
            var arr = [];
            if (this.formPageConfig) {
                jo.forEach(this.formPageConfig.elementList, function (item) {
                    arr.push(item);
                });
            }
            return arr;
        },
        // 表单配置选中项
        formConfigActiveEleWrap() {
            if (!this.formConfigActiveEle) {
                return {};
            }
        },
        // 当前选中组件的id
        formConfigActiveEleId() {
            return this.formConfigActiveEle ? this.formConfigActiveEle.id : '';
        },
        // 可选的基础组件列表
        formConfigBaseComponentList() {
            return jo.object2Array(PAGE_CONFIG_COMPONENT_META, function (k, v) {
                return {
                    type: k,
                    text: v.name,
                };
            });
        },
        // 可选的样式表集合
        formConfigClassOptionList() {
            return [
                {value: 'qy-flex', text: '水平flex'},
                {value: 'qy-flex-y', text: '垂直flex'},
                {value: 'qy-flex-1', text: 'flex=1'},
                {value: 'qy-height-60', text: '高度60px'},
                {value: 'qy-width-250', text: '宽度250px'},
                {value: 'qy-width-100p', text: '宽度100%'},
                {value: 'qy-height-100p', text: '高度100%'},
                {value: 'qy-padding-15', text: '内边距15px'},
            ];
        },
        // 可选的内联样式集合
        formConfigStyleOptionList() {
            var arr = [];
            var _this = this;
            jo.forEach(PAGE_CONFIG_STYLE_META, function (item) {
                arr.push(_this.convertStyleMeta(item));
            });
            return arr;
        },
        // 可选的组件属性
        formConfigAttrOptionList() {
            var arr = [];
            var _this = this;
            if (this.formConfigActiveEle) {
                var config = PAGE_CONFIG_COMPONENT_META[this.formConfigActiveEle.type];
                if (config) {
                    jo.forEach(config.attrDescriptions, function (item) {
                        arr.push(item);
                    });
                }
            }
            return arr;
        },
    },
    methods: {
        // 删除当前节点
        removeActiveEle() {
            if (this.formConfigActiveEle) {
                this.removeEleWrap(this.formConfigActiveEle);
                this.formConfigActiveEle = null;
            }
        },
        // 移动组件位置, moveEle:要移动的元素, targetEle:目标位置元素, position:移动后相对目标元素的位置（before、after、inner）
        moveComponentElePosition(moveEle, targetEle, position) {
            if (!moveEle || !targetEle || !position) {
                console.warn('[移动组件位置] 存在无效参数:', arguments);
                return;
            }
            if (position !== 'before' && position !== 'after' && position !== 'inner') {
                console.warn('[移动组件位置] 位置参数非法:', position);
                return;
            }
            // 先从原来的位置删除
            this.removeEleWrap(moveEle);
            console.info('[移动组件位置] 已从老位置删除,准备插入到新位置--');
            if (position === 'inner') {
                if (!targetEle.childrenList) {
                    targetEle.childrenList = [];
                }
                targetEle.childrenList.push(moveEle);
            } else {
                // 找到目标对象所处的集合, 然后在合适的地方插入
                var list = this.findEleOriginList(targetEle, this.formPageConfig.elementList) || this.formPageConfig.elementList;
                // 目标对象在集合的位置
                var idx = this.findEleIdx(targetEle, list);
                if (idx < 0) {
                    // 目标位置匹配失败则默认放到最后, 正常情况到不了这里
                    list.push(moveEle);
                    console.warn('[移动组件位置] 目标位置匹配失败,默认放到集合最后');
                } else {
                    if (position === 'before') {
                        list.splice(idx, 0, moveEle);
                    } else {//position === 'after'
                        list.splice(idx + 1, 0, moveEle);
                    }
                }
            }
        },
        // dom树节点是否可以被拖拽
        domTreeAllowDrag() {
            return true;
        },
        // dom树节点是否可以被拖放, prev/next/inner
        domTreeAllowDrop(dragNode, dropNode, position) {
            if (position === 'inner' && dropNode.data.canAsParent === false) {
                // console.info('[dom树节点是否可以被拖放] 当前拖放节点不支持作为父节点', dropNode)
                return false;
            }
            return true;
        },
        // dom树节点拖放, 共四个参数，依次为：被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置（before、after、inner）、event
        domTreeDrop(dragNode, dropNode, position, event) {
            // this.moveComponentElePosition(dragNode.data, dropNode.data, position);
        },
        // 页面配置中组件选中
        domTreeClick(clickItem, clickNode, tree, event) {
            if (!this.formConfigActiveEle || this.formConfigActiveEle.id !== clickItem.id) {
                this.formConfigActiveEle = clickItem;
            }
        },
        // 转换样式元数据, 转为选择器需要的格式
        convertStyleMeta(item) {
            var _this = this;
            var obj = {
                value: item.name,
                label: item.text ? item.name + '：' + item.text : item.name
            }
            if (item.children) {
                // obj.label = item.text ? item.text + '（'+item.name+'）' : item.name;
                obj.children = [];
                jo.forEach(item.children, function (child) {
                    obj.children.push(_this.convertStyleMeta(child));
                });
            }
            return obj;
        },
        // 添加内联样式
        addStyle() {
            if (!this.formConfigActiveEle.styleList) {
                this.formConfigActiveEle.styleList = [];
            }
            this.formConfigActiveEle.styleList.push({});
        },
        removeStyle(idx) {
            this.formConfigActiveEle.styleList.splice(idx, 1);
        },
        // 添加属性
        addAttr() {
            if (!this.formConfigActiveEle.attrList) {
                this.formConfigActiveEle.attrList = [];
            }
            this.formConfigActiveEle.attrList.push({});
        },
        removeAttr(idx) {
            this.formConfigActiveEle.attrList.splice(idx, 1);
        },
        // 左侧选项转实际元素对象
        convertOptionToEle(option) {
            var obj = {
                id: option.type + '_' + jo.getUUID(6).toLowerCase(),
                type: option.type,
                subType: option.subType,
                classList: jo.copyObjectDeep(option.classList || []),
                styleList: jo.copyObjectDeep(option.styleList || []),
                attrList: jo.copyObjectDeep(option.attrList || []),
                eventList: jo.copyObjectDeep(option.eventList || []),
                childrenList: [],
                canAsParent: option.type !== 'divider',//是否可以作为父节点
            };
            if (option.childrenList && option.childrenList.length > 0) {
                for (let i = 0; i < option.childrenList.length; i++) {
                    var item = option.childrenList[i];
                    obj.childrenList.push(this.convertOptionToEle(item));
                }
            }
            return obj;
        },
        // 拖放到表单配置容器
        dropFormConfigContainer(event) {
            // console.info('在表单容器拖放', event, this.dragContext);
            if (this.dragContext.dragType === this.formConfigDragType.option.code) {
                if (this.dragContext.dragEleOption) {
                    this.formPageConfig.elementList.push(this.convertOptionToEle(this.dragContext.dragEleOption));
                }
            } else {
                console.info('表单容器不支持此拖拽类型', this.dragContext);
            }
        },
        dragStartEleOption(event, ele) {
            console.info('开始拖拽Option', ele)
            this.dragContext = {
                dragType: this.formConfigDragType.option.code,
                dragEleOption: ele,
            };
        },
        // 拖拽左侧组件选项结束
        dragEndEleOption(event, ele) {
            console.info('结束拖拽Option', ele)
            this.dragContext = {};
            this.clearDropStyle();
        },
        // 组件包装器拖拽开始
        dragStartEleWrap(event, ele) {
            console.info('开始拖拽Wrap', ele)
            this.dragContext = {
                dragType: this.formConfigDragType.inner.code,
                dragEleOption: ele,
            };
        },
        // 组件包装器拖拽结束
        dragEndEleWrap(event, ele) {
            console.info('结束拖拽Wrap', ele)
            this.dragContext = {};
            this.clearDropStyle();
        },
        // 清除拖放样式
        clearDropStyle() {
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-center');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-before');
            $('.form-config-ele-wrap').removeClass('form-config-ele-wrap-drop-after');
        },
        // 组件包装器在目标对象上拖动, ele: 目标对象
        dragOverEleWrap(event, ele) {
            if (!ele || !this.dragContext.dragEleOption) {
                console.info('[dragOverEleWrap] 拖拖拽和拖放的存在无效对象,pass');
                return;
            }
            if (this.eleIncludeAnotherEle(ele, this.dragContext.dragEleOption)) {
                // console.info('[dragOverEleWrap] 拖拖拽和拖放的是同一个对象或者包含拖放对象,pass', this.dragContext.dragEleOption, ele);
                return;
            }
            // 鼠标在目标对象的位置
            var position = jo.getPositionDetail(event, 'form-config-ele-wrap');
            // 清空样式
            this.clearDropStyle();
            if (position.atCenterOf9) {
                // 放到目标对象的子节点
                $(event.currentTarget).addClass('form-config-ele-wrap-drop-center');
            } else if (position.atLeftOf9 || position.atUpOf9) {
                // 左/上则放到目标前面
                $(event.currentTarget).addClass('form-config-ele-wrap-drop-before');
            } else {
                // 右/下放到目标后面
                // 定位失败默认放到目标后面
                $(event.currentTarget).addClass('form-config-ele-wrap-drop-after');
            }
        },
        // 组件包装器拖放
        dropEleWrap(event, ele) {
            // console.info('在表单容器拖放', event, this.dragContext);
            if (!ele || !this.dragContext.dragEleOption) {
                console.info('拖拖拽和拖放的存在无效对象,pass');
                return;
            }
            if (this.eleIncludeAnotherEle(ele, this.dragContext.dragEleOption)) {
                console.info('拖拖拽和拖放的是同一个对象或者包含拖放对象,pass', this.dragContext.dragEleOption, ele);
                return;
            }
            var _this = this;
            var dragEle;
            if (this.dragContext.dragType === this.formConfigDragType.option.code) {
                if (this.dragContext.dragEleOption) {
                    dragEle = this.convertOptionToEle(this.dragContext.dragEleOption);
                }
            } else if (this.dragContext.dragType === this.formConfigDragType.inner.code) {
                if (this.dragContext.dragEleOption && ele) {
                    if (!ele.childrenList) {
                        ele.childrenList = [];
                    }
                    // 从原来位置删除
                    this.removeEleWrap(this.dragContext.dragEleOption);
                    dragEle = this.dragContext.dragEleOption;
                }
            } else {
                console.info('元素wrap不支持此拖拽类型', this.dragContext);
            }

            if (dragEle) {
                // 放到目标对象的对应位置
                var position = jo.getPositionDetail(event, 'form-config-ele-wrap');
                if (position.atCenterOf9) {
                    // 放到目标对象的子节点
                    if (!ele.childrenList) {
                        ele.childrenList = [];
                    }
                    ele.childrenList.push(dragEle);
                } else {
                    // 拖放目标在哪个集合里
                    var list = this.findEleOriginList(ele, this.formPageConfig.elementList) || this.formPageConfig.elementList;
                    // 拖放目标在集合的位置
                    var idx = this.findEleIdx(ele, list);
                    if (idx < 0) {
                        // 目标位置匹配失败则默认放到最后, 正常情况到不了这里
                        list.push(dragEle);
                        console.warn('[组件包装器拖放] 目标位置匹配失败,拖拽对象和目标对象打印:', this.dragContext, ele);
                    } else {
                        if (position.atLeftOf9 || position.atUpOf9) {
                            // 左/上则放到目标前面
                            list.splice(idx, 0, dragEle);
                        } else {
                            // 右/下放到目标后面
                            // 定位失败默认放到目标后面
                            list.splice(idx + 1, 0, dragEle);
                        }
                    }
                }

            }
        },
        // 拖拽在目标对象上移动, 啥也不干, 没有这个事件则拖放事件不生效
        dragOverNothing(event) {
        },
        // dragOverEleOption(event, ele) {
        //     console.info('拖拽移动', ele)
        // },
        // dropEleOption(event, ele) {
        //     console.info('拖放', ele)
        // },


        // 判断元素是否在另一个元素中, 也就是是否相同或者是子节点
        eleIncludeAnotherEle(ele, another) {
            if (ele.id == another.id) {
                return true;
            }
            if (another.childrenList) {
                for (let i = 0; i < another.childrenList.length; i++) {
                    var item = another.childrenList[i];
                    if (this.eleIncludeAnotherEle(ele, item)) {
                        return true;
                    }
                }
            }
            return false;
        },
        // 查找元素在哪个集合中
        findEleOriginList(eleWrap, list) {
            if (list && list.length > 0) {
                // 判断在不在list
                for (let i = 0; i < list.length; i++) {
                    var item = list[i];
                    if (item.id == eleWrap.id) {
                        return list;
                    }
                }
                // 判断在不在孩子节点
                for (let i = 0; i < list.length; i++) {
                    var item = list[i];
                    if (item.childrenList) {
                        var list2 = this.findEleOriginList(eleWrap, item.childrenList);
                        if (list2) {
                            return list2;
                        }
                    }
                }
            }
            return null;
        },
        // 从表单配置的元素列表中删除指定元素
        removeEleWrap(eleWrap) {
            this.removeEleWrapFromList(eleWrap, this.formPageConfig.elementList);
        },
        // 删除元素从一个列表中
        removeEleWrapFromList(eleWrap, eleList) {
            if (eleList) {
                var _this = this;
                var delIdx = this.findEleIdx(eleWrap, eleList);
                if (delIdx >= 0) {
                    eleList.splice(delIdx, 1);
                    console.info('[删除元素老位置] 位置:', delIdx);
                } else {
                    // 再从子节点中删除
                    jo.forEach(eleList, function (item, i) {
                        if (item.childrenList) {
                            _this.removeEleWrapFromList(eleWrap, item.childrenList);
                        }
                    });
                }
            }
        },
        // 获取元素在集合的位置
        findEleIdx(eleWrap, eleList) {
            var idx = -1;
            if (eleList) {
                jo.forEach(eleList, function (item, i) {
                    if (item.id == eleWrap.id) {
                        if (idx >= 0) {
                            console.error('[获取元素在集合的位置] 重复匹配到元素,上次匹配索引+本次索引+集合输出:', idx, i, eleList);
                        }
                        idx = i;
                    }
                });
            }
            return idx;
        },

    }
};